package system.service.sys.impl;

import com.github.pagehelper.PageInfo;
import framework.exceptions.BusinessException;
import framework.runtime.SystemContext;
import framework.vo.ResultList;
import lombok.Getter;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import system.entity.SysTaskJob;
import system.mapper.SysTaskJobMapper;
import system.service.sys.SysTaskJobService;
import system.task.Task;
import system.task.TaskManager;
import system.task.defined.TaskRunStatus;
import system.task.errors.TaskException;
import system.task.utils.TaskUtil;
import system.task.vo.SysTaskRunning;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class SysTaskJobServiceImpl implements SysTaskJobService {
    @Autowired
    @Getter
    private SysTaskJobMapper mapper;
    @Lazy
    @Autowired
    private TaskManager taskManager;

    @Override
    public int updateByName(SysTaskJob param) {
        return getMapper().updateByName(param);
    }

    @Override
    public int updateBody(SysTaskJob param) {
        return getMapper().updateBody(param);
    }

    @Override
    public SysTaskRunning loadInfo(Long id) {
        SysTaskJob info = mapper.loadById(id);
        if (info == null) {
            String msg = SystemContext.getMessageDefault("task.not.found", "Not found task " + id);
            throw new BusinessException(msg);
        }

        TaskUtil.cleanJobMaxTime(info);
        SysTaskRunning running = new SysTaskRunning();
        Task task = null;
        try {
            task = this.taskManager.getTask(info.getName());
        } catch (TaskException e) {
            log.error("load task info failed, " + e.getMessage(), e);
        }
        if (task != null) {
            TaskUtil.fillRunning(info, task, running);
        }

        return running;
    }

    @Override
    public ResultList<SysTaskRunning> loadRunning(SysTaskJob param, Integer pageIndex, Integer pageSize) {
        PageInfo<SysTaskJob> info = this.list(param, pageIndex, pageSize);
        TaskUtil.cleanJobMaxTime(info.getList());
        List<SysTaskRunning> runningList = new ArrayList<>();
        for (SysTaskJob job : info.getList()) {
            SysTaskRunning running = new SysTaskRunning();
            Task task = null;
            try {
                task = this.taskManager.getTask(job.getName());
            } catch (TaskException e) {
                log.error("load task info failed, " + e.getMessage(), e);
            }
            if (task == null) {
                task = new Task();
                BeanUtils.copyProperties(job, task);
                task.setRunStatus(TaskRunStatus.FAILED);
                task.setRunRemarks("Wait load task or " + job.getSchedule() + " invalid");
            }
            TaskUtil.fillRunning(job, task, running);
            runningList.add(running);
        }
        return new ResultList<>(runningList, info.getTotal(), info.getPageNum(), info.getPageSize());
    }

    @SneakyThrows
    @Override
    public List<Date> loadTriggerTimes(String name, int size, Date afterTime) {
        return this.taskManager.getTriggerTimes(name, size, afterTime);
    }
}